home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus 1995 #5 & #6
/
Amiga Plus CD - 1995 - No. 5 and 6.iso
/
tex
/
archives
/
pbmtopk.lzh
/
pbmtopk
/
src
/
pktopbm.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-16
|
9KB
|
383 lines
/*
pktopbm, adapted from "pktopx in C by Tomas Rokicki" by AJCD 1/8/90
compile with: cc -lpbm -o pktopbm pktopbm.c
*/
#include <stdio.h>
#include <pbm.h>
#define NAMELENGTH 80
#define MAXROWWIDTH 3200
#define MAXPKCHAR 256
#define round(a) ((int)(a+0.5))
typedef int integer ;
typedef unsigned char quarterword ;
typedef char boolean ;
typedef quarterword eightbits ;
typedef FILE *bytefile ;
bytefile pkfile ;
char pkname[NAMELENGTH+1] ;
integer pkloc ;
integer i, j ;
char *filename[MAXPKCHAR] ;
bit **bitmap = NULL ;
integer dynf ;
eightbits inputbyte ;
eightbits bitweight ;
integer repeatcount ;
integer flagbyte ;
add_suffix(name, suffix)
char *name, *suffix ;
{
int haveext = 0;
if (name) {
while (*name) {
if (*name == '/') haveext = 0 ;
else if (*name == '.') haveext = 1 ;
name++ ;
}
if (!haveext) {
*name++ = '.';
strcpy(name,suffix) ;
}
}
}
initialize()
{
integer i ;
fprintf(stderr, "This is PKtoPBM, C Version 2.3\n") ;
for (i = 0 ; i < MAXPKCHAR ; i ++) filename[i] = NULL ;
}
jumpout()
{
exit(1) ;
}
openpkfile()
{
if ((pkfile = fopen(pkname, "r")) == NULL) {
fprintf(stderr, " Can't open pk file %s!\n", pkname) ;
}
pkloc = 0 ;
}
eightbits pkbyte()
{
pkloc++ ;
return(getc(pkfile)) ;
}
integer get16()
{
integer a = pkbyte() ;
return((a<<8) + pkbyte()) ;
}
integer get32()
{
integer a = get16() ;
if (a > 32767) a -= 65536 ;
return((a<<16) + get16()) ;
}
integer getnyb()
{
eightbits temp ;
if (bitweight == 0) {
inputbyte = pkbyte() ;
bitweight = 16 ;
}
temp = inputbyte / bitweight ;
inputbyte -= temp * bitweight ;
bitweight >>= 4 ;
return(temp) ;
}
boolean getbit()
{
boolean temp ;
bitweight >>= 1 ;
if (bitweight == 0) {
inputbyte = pkbyte() ;
bitweight = 128 ;
}
temp = (inputbyte >= bitweight) ;
if (temp) inputbyte -= bitweight ;
return(temp) ;
}
integer pkpackednum()
{
integer i, j, k ;
i = getnyb() ;
if (i == 0) {
do {
j = getnyb() ;
i++ ;
} while (!(j != 0)) ;
while (i > 0) {
j = (j<<4) + getnyb() ;
i-- ;
}
return(j - 15 +((13 - dynf)<<4) + dynf) ;
} else if (i <= dynf) return(i) ;
else if (i < 14) return(((i - dynf - 1)<<4) + getnyb() + dynf + 1) ;
else {
if (i == 14) repeatcount = pkpackednum() ;
else repeatcount = 1 ;
return(pkpackednum()) ;
}
}
skipspecials()
{
integer i, j, k ;
do {
flagbyte = pkbyte() ;
if (flagbyte >= 240)
switch(flagbyte) {
case 240:
case 241:
case 242:
case 243:
i = 0 ;
for (j = 240 ; j <= flagbyte ; j ++) i = (i<<8) + pkbyte() ;
for (j = 1 ; j <= i ; j ++) k = pkbyte() ;
break ;
case 244:
i = get32() ;
break ;
case 245:
break ;
case 246:
break ;
case 247:
case 248:
case 249:
case 250:
case 251:
case 252:
case 253:
case 254:
case 255:
fprintf(stderr, " Unexpected flag byte %d!\n", flagbyte) ;
jumpout() ;
}
} while (!((flagbyte < 240) || (flagbyte == 245))) ;
}
usage()
{
fprintf(stderr, " Usage: pktopbm pkfile[.pk] [[-c num] pbmfile]...\n");
jumpout() ;
}
dialog(gargc, gargv)
int gargc ;
char **gargv ;
{
integer car ;
if (--gargc < 1) usage() ;
strcpy(pkname, *++gargv) ;
add_suffix(pkname, "pk") ;
car = 0 ;
while (++gargv, --gargc) {
if (gargv[0][0] == '-' && gargv[0][1])
switch (gargv[0][1]) {
case 'c':
if (gargv[0][2]) car = atoi(*gargv+2) ;
else if (++gargv, --gargc) car = atoi(*gargv) ;
else usage() ;
break ;
default:
usage() ;
} else if (car < 0 || car >= MAXPKCHAR) {
fprintf(stderr, " Character must be in range 0 to %d (-c)!\n",
MAXPKCHAR-1) ;
jumpout() ;
} else filename[car++] = *gargv ;
}
}
main(argc, argv)
int argc ;
char *argv[] ;
{
integer endofpacket ;
integer designsize ;
integer checksum ;
integer hppp, vppp ;
integer cheight, cwidth ;
integer horesc ;
integer packetlength ;
integer rowsleft ;
boolean turnon ;
integer hbit ;
integer count ;
integer rp ;
integer i, j, k ;
integer car ;
bit row[MAXROWWIDTH+1] ;
initialize() ;
dialog(argc, argv) ;
openpkfile() ;
if (pkbyte() != 247) {
fprintf(stderr, " Bad pk file (pre command missing)!\n") ;
jumpout() ;
}
if (pkbyte() != 89) {
fprintf(stderr, " Wrong version of packed file!\n") ;
jumpout() ;
}
j = pkbyte() ;
for (i = 1 ; i <= j ; i ++) k = pkbyte() ;
designsize = get32() ;
checksum = get32() ;
hppp = get32() ;
vppp = get32() ;
if (hppp != vppp) fprintf(stderr, " Warning: aspect ratio not 1:1!\n") ;
skipspecials() ;
while (flagbyte != 245) {
dynf = (flagbyte>>4) ;
flagbyte &= 15 ;
turnon = (flagbyte >= 8) ;
if (turnon) flagbyte &= 7 ;
if (flagbyte == 7) {
packetlength = get32() ;
car = get32() ;
endofpacket = packetlength + pkloc ;
if ((car >= MAXPKCHAR) || (car < 0)) goto lab9997 ;
i = get32() ; /* tfmwidth */
horesc = get32() ;
i = get32() ;
cwidth = get32() ;
cheight = get32() ;
if ((cwidth < 0) || (cheight < 0) || (cwidth > 65535) || (cheight > 65535)) goto lab9997 ;
i = get32() ;
j = get32() ;
} else if (flagbyte > 3) {
packetlength =((flagbyte - 4)<<16) + get16() ;
car = pkbyte() ;
endofpacket = packetlength + pkloc ;
if (car >= MAXPKCHAR) goto lab9997 ;
i = pkbyte() ; /* tfmwidth */
i = get16() ;
horesc = get16() ;
cwidth = get16() ;
cheight = get16() ;
i = get16() ;
j = get16() ;
} else {
packetlength = (flagbyte<<8) + pkbyte() ;
car = pkbyte() ;
endofpacket = packetlength + pkloc ;
if (car >= MAXPKCHAR) goto lab9997 ;
i = pkbyte() ; /* tfmwidth */
i = get16() ;
horesc = pkbyte() ;
cwidth = pkbyte() ;
cheight = pkbyte() ;
i = pkbyte() ;
j = pkbyte() ;
}
if (filename[car]) {
bitmap = pbm_allocarray(cwidth, cheight) ;
if (bitmap == NULL) {
fprintf(stderr, " Out of memory allocating bitmap!\n") ;
jumpout() ;
}
} else goto lab9997 ;
bitweight = 0 ;
if (dynf == 14) {
for (i = 0 ; i < cheight ; i ++)
for (j = 0 ; j < cwidth ; j ++) {
if (getbit())
bitmap[i][j] = PBM_BLACK ;
else
bitmap[i][j] = PBM_WHITE ;
}
} else {
rowsleft = cheight ;
hbit = cwidth ;
repeatcount = rp =0 ;
while (rowsleft > 0) {
count = pkpackednum() ;
while (count > 0) {
if (count < hbit) {
hbit -= count ;
while (count--) {
if (turnon)
row[rp++] = PBM_BLACK ;
else
row[rp++] = PBM_WHITE ;
}
} else {
count -= hbit ;
while (hbit--) {
if (turnon)
row[rp++] = PBM_BLACK ;
else
row[rp++] = PBM_WHITE ;
}
for (i = 0; i <= repeatcount; i++)
for (j = 0; j < cwidth; j++)
bitmap[i + cheight-rowsleft][j] = row[j] ;
rowsleft -= repeatcount + 1;
repeatcount = rp = 0 ;
hbit = cwidth ;
}
}
turnon = ! turnon ;
}
if ((rowsleft != 0) || (hbit != cwidth)) {
fprintf(stderr, " Bad pk file (more bits than required)!\n") ;
jumpout() ;
}
}
if (endofpacket != pkloc) {
fprintf(stderr, " Bad pk file (bad packet length)!\n") ;
jumpout() ;
}
/* output bitmap to file */
{
FILE *fp ;
if (!strcmp(filename[car], "-"))
fp = stdout ;
else {
if ((fp = fopen(filename[car], "w")) == NULL) {
fprintf(stderr, " Can't open file %s!\n", filename[car]) ;
jumpout() ;
}
}
filename[car] = NULL;
pbm_writepbm(fp, bitmap, cwidth, cheight, 0) ;
pbm_freearray(bitmap, cheight) ;
if (fp != stdout) (void)fclose(fp) ;
}
goto lab9998 ;
lab9997: while (pkloc != endofpacket) i = pkbyte() ;
if (car < 0 || car >= MAXPKCHAR)
fprintf(stderr, " Character %d out of range!\n", car) ;
lab9998: skipspecials() ;
}
while (! feof(pkfile)) i = pkbyte() ;
pkloc-- ;
for (car = 0; car < MAXPKCHAR; car++)
if (filename[car])
fprintf(stderr, " Warning: No character in position %d (file %s).\n",
car, filename[car]) ;
fprintf(stderr, "%d bytes read from packed file.\n", pkloc) ;
exit(0);
}